import Level from 'level-ts'

class KvDB {
    private prefix: string;
    private database: Level;

    constructor(database: Level, name: string) {
        this.prefix = name + '::'
        this.database = database
    }

    async pop() {
        const iterator = this.database.iterate({ all: this.prefix, keys: true })
        const result = await iterator.next()
        await iterator.end()
        if (!result) {
            return undefined
        }

        if (typeof result === 'string') {
            let key = result as string 
            await this.database.del(key)
            key = key.substring(this.prefix.length)
            return { key }
        }

        let {key, value} = result
        key = key.substring(this.prefix.length)
        return {key, value}
    }

    async get(key: string) {
        key = this.prefix + key
        try {
            const value = await this.database.get(key)
            return value
        } catch (error) {
        }
    }

    async add(key: string, value?: any) {
        key = this.prefix + key
        if (!value) {
            value = ''
        }
        return this.database.put(key, value)
    }

    async remove(key: string) {
        key = this.prefix + key
        return this.database.del(key)
    }

    async forEach(callbackfn: (key: string, value: any) => Promise<boolean>) {
        const iterator = this.database.iterate({ all: this.prefix, keys: true })
        while (true) {
            const result = await iterator.next()
            if (!result) {
                await iterator.end()
                return
            }

            let {key, value} = result
            key = key.substring(this.prefix.length)
            const ok = await callbackfn(key, value)
            if (!ok) {
                await iterator.end()
                return
            }
        }
    }
}

export { KvDB }
